<?php
/**
 * RedXenon Framework
 * 
 * LICENSE
 * 
 * This source file is subject to the New BSD license that is bundled
 * with this package in the file LICENSE.txt
 * A copy of this license can be found in the world-wide-web at this URL:
 * http://www.redxenon.com/license/new-bsd-license.txt
 */

/** File Manager for the template file */
require_once(dirname(dirname(__FILE__))."/File/RXFileManager.php");
require_once(dirname(dirname(__FILE__))."/View/RXViewTemplate.php");
require_once(dirname(dirname(__FILE__))."/Date/RXDate.php");

/**
 * RedXenon Cache (RXCacheTemplate.php)
 * Defines methods to be applied to templates
 * 
 * @category RedXenon
 * @package RedXenon_Cache
 * @copyright Copyright (c) 2011 Red Xenon (http://www.redxenon.com)
 * @version $Id: RXCacheTemplate.php 1.0 2011-10-08 $ 
 */
class RXCacheTemplate{
	
	protected $className;	
	private $cacheDirectory;
	private $cacheFilePath;
	private $debug;
	private $regenerate;
	protected $cacheTime;
	protected $cacheKeyName;
	
	public function __construct(){
		$this->className = get_class($this);
	}
	
	public function getCacheOutput(){
		$this->checkCacheDirectory();
		$this->generateCacheFilePath();
		$this->checkGetVariables();
		$this->getMaximumExpiringTime();
		
		$fileManager = new RXFileManager();
		
		if($this->debug)
			echo "<span style=\"color:#F00; font-family:Tahoma,Arial,sans-serif;font-size:8pt;\">--- BEGINING CACHE DEBUG OUTPUT ---<br/>";
		
		try{
			if(@file_exists($this->cacheFilePath)){
				$file = new RXFile($this->cacheFilePath);
				$expirationTime = $file->getLastModificationTime()->getUnixTime() + $this->cacheTime;
				$expirationDate = new RXDate();
				$expirationDate->setUnixTime($expirationTime);
				if($this->debug){
					if($this->cacheTime != 0)
						echo "CACHE FILE EXISTS<br/>".$this->cacheFilePath."<br/>Expires in ".$expirationDate->getDate()."<br/>";
					else
						echo "CACHE FILE EXISTS<br/>".$this->cacheFilePath."<br/>Expires NEVER<br/>";
				}
								
				$fileManager->setFile($file);
				if(($this->cacheTime!= 0 && time() > $expirationTime) || $this->regenerate){
					if($this->debug)				
						echo "REGENERATING CACHE<br/>";
					$output = $this->regenerateCache();
				}else{
					if($this->debug)				
						echo "READING CACHE<br/>";
					$output = $fileManager->read();
				}
			}else{
				if($this->debug)				
						echo "REGENERATING CACHE<br/>";
				$output = $this->regenerateCache();
			}
			if($this->debug)
				echo "--- CACHE DEBUG OUTPUT FINISHED ---</span>";
			return $output;
			
		}catch(Exception $e){
			if($this->debug){
				echo "AN EXCEPTION OCURRED: ".$e->getMessage()."<br/>TRACE: <br/>".nl2br($e->getTraceAsString())."<br/>";
			}
		}		
	}
	
	public function checkGetVariables(){
		$this->debug = FALSE;
		$this->regenerate = FALSE;
		
		if(@constant('CACHE_DEBUG_PARAMETER')){
			if(@$_GET[CACHE_DEBUG_PARAMETER])
				$this->debug = TRUE;
		}
		
		if(@constant('CACHE_REGENERATE_PARAMETER')){
			if(@$_GET[CACHE_REGENERATE_PARAMETER])
				$this->regenerate = TRUE;
		}		
	}	
	
	public function regenerateCache(){
		$output = $this->getOutput();
		$fileManager = new RXFileManager();
		$fileManager->setNewFile($this->cacheFilePath);
		$fileManager->open("w");
		$fileManager->write($output);
		return $output;
	}
	
	public function generateCacheFilePath(){
		$key = $this->className;
		if($this->cacheKeyName){
			$key .= $this->cacheKeyName;
		}
		
		$this->cacheFilePath = $this->cacheDirectory.substr(
			md5($key), 0, 4).'/'.$key.'.cache';
	}
	
	public function getMaximumExpiringTime(){
		if(!isset($this->cacheTime)){
			if(@constant('CACHE_TIME'))
				$this->cacheTime = CACHE_TIME;
			else 
				$this->cacheTime = 0;
		}
	}
	
	public function checkCacheDirectory(){
		if(@constant('CACHE_DIRECTORY')){
			$this->cacheDirectory = CACHE_DIRECTORY;
		}else{
			$this->cacheDirectory = "/CACHE/";
		}
		
		if(!$this->cacheDirectory[strlen($this->cacheDirectory) - 1] == '/'){
			$this->cacheDirectory.'/';
		}
		
		if(!@is_dir($this->cacheDirectory)){
			mkdir($this->cacheDirectory);
		}
		
		if(!@is_dir($this->cacheDirectory.substr(md5($this->className.$this->cacheKeyName), 0, 4))){
				mkdir($this->cacheDirectory.substr(md5($this->className.$this->cacheKeyName), 0, 4));
		}
	}
	
	public function setCacheTime($time){
		$this->cacheTime = $time;
	}
	
	public function setCacheKeyName($key){
		$this->cacheKeyName = $key;
	}
}